home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / 第1特集Plug-in / Photoshop / Developer's Kit.sit / Developer's Kit / Think C Examples / Export / DummySave.c next >
Text File  |  1991-02-02  |  8KB  |  441 lines

  1. /*
  2.     File: DummySave.c
  3.  
  4.     Copyright 1990 by Thomas Knoll.
  5.  
  6.     Think C source file for DummySave example.
  7. */
  8.  
  9. #include <MacTypes.h>
  10. #include <MemoryMgr.h>
  11. #include <ResourceMgr.h>
  12. #include <Quickdraw.h>
  13. #include <DialogMgr.h>
  14. #include <OSUtil.h>
  15. #include <PackageMgr.h>
  16. #include <StdFilePkg.h>
  17. #include <SysErr.h>
  18. #include <ToolboxUtil.h>
  19. #include <pascal.h>
  20. #include <SetUpA4.h>
  21.  
  22. #include "ExportInterface.h"
  23.  
  24. #define nil 0L
  25. #define Length(string) (*(unsigned char *)(string))
  26.  
  27. /* The value of global variables are not preserved between invocations
  28.    of the plug-in, since the plug-in's resource file is closed. To keep
  29.    values around longer, make them part of the following structure. */
  30.  
  31. typedef struct TPermanent {
  32.     short dummy1;                /* None are actually used in this example */
  33.     } TPermanent;
  34.  
  35. TPermanent gPermanent;
  36.  
  37. short gResult;
  38. ExportRecordPtr gStuff;
  39.  
  40. short gFRefNum;
  41. short gVRefNum;
  42.  
  43. /*****************************************************************************/
  44.  
  45. /* Calls the host's TestAbort function */
  46.  
  47. Boolean TestAbort (void)
  48.  
  49.     {
  50.     return CallPascalB (gStuff->abortProc);
  51.     }
  52.  
  53. /*****************************************************************************/
  54.  
  55. /* Calls the host's UpdateProgress procedure */
  56.  
  57. void UpdateProgress (done, total)
  58.  
  59. long done;
  60. long total;
  61.  
  62.     {
  63.     CallPascal (done, total, gStuff->progressProc);
  64.     }
  65.  
  66. /*****************************************************************************/
  67.  
  68. /* Sets the global variables to their default values. */
  69.  
  70. void InitGlobals (void)
  71.  
  72.     {
  73.     }
  74.  
  75. /*****************************************************************************/
  76.  
  77. /* Centers a dialog template 1/3 of the way down on the main screen. */
  78.  
  79. void CenterDialog (dt)
  80.  
  81. DialogTHndl dt;
  82.  
  83. #define menuHeight 20
  84.  
  85.     {
  86.     Rect r;
  87.     short width;
  88.     short height;
  89.  
  90.     width  = screenBits.bounds.right;
  91.     height = screenBits.bounds.bottom;
  92.  
  93.     r = (**dt).boundsRect;
  94.     OffsetRect (&r, -r.left, -r.top);
  95.     OffsetRect (&r, (width - r.right) / 2,
  96.                     (height - r.bottom - menuHeight) / 3 + menuHeight);
  97.     (**dt).boundsRect = r;
  98.     }
  99.  
  100. #undef menuHeight
  101.  
  102. /*****************************************************************************/
  103.  
  104. /* Displays the about dialog box for the plug-in module. */
  105.  
  106. void DoAbout (void)
  107.  
  108. #define dialogID 17000
  109.  
  110.     {
  111.     short item;
  112.     DialogPtr dp;
  113.     DialogTHndl dt;
  114.  
  115.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  116.     HNoPurge ((Handle) dt);
  117.     CenterDialog (dt);
  118.  
  119.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  120.  
  121.     ModalDialog (nil, &item);
  122.  
  123.     DisposDialog (dp);
  124.     HPurge ((Handle) dt);
  125.     }
  126.  
  127. #undef dialogID
  128.  
  129. /*****************************************************************************/
  130.  
  131. /* Prepare to export an image.  If the plug-in module needs only a limited
  132.    amount of memory, it can lower the value of the 'maxData' field. */
  133.  
  134. void DoPrepare (void)
  135.  
  136.     {
  137.     if (gStuff->maxData > 0x80000)
  138.         gStuff->maxData = 0x80000;
  139.     }
  140.  
  141. /*****************************************************************************/
  142.  
  143. /* Request next block of the image */
  144.  
  145. void RequestNext (top)
  146.  
  147. short top;
  148.  
  149.     {
  150.     long count;
  151.     
  152.     /* Compute maximum number of rows we should request at once */
  153.  
  154.     count = gStuff->maxData / gStuff->imageSize.h / gStuff->planes;
  155.  
  156.     if (count < 1) count = 1;
  157.  
  158.     /* Request next block of the image */
  159.  
  160.     gStuff->loPlane = 0;
  161.     gStuff->hiPlane = gStuff->planes - 1;
  162.  
  163.     gStuff->theRect.left  = 0;
  164.     gStuff->theRect.right = gStuff->imageSize.h;
  165.     gStuff->theRect.top   = top;
  166.  
  167.     if (top + count > gStuff->imageSize.v)
  168.         gStuff->theRect.bottom = gStuff->imageSize.v;
  169.     else
  170.         gStuff->theRect.bottom = top + count;
  171.  
  172.     }
  173.  
  174. /*****************************************************************************/
  175.  
  176. /* Verifies that the image mode is supported.  Prompts the user for
  177.    a file name to save the image to, and requests the first block of
  178.    of image data. */
  179.  
  180. void DoStart (void)
  181.  
  182. #define kStringsID 17000
  183.  
  184.     {
  185.     OSErr err;
  186.     Point where;
  187.     Str255 prompt;
  188.     SFReply reply;
  189.     DialogTHndl dt;
  190.  
  191.     /* This plug-in does not support bitmap images */
  192.  
  193.     if (gStuff->imageMode == exportModeBitmap)
  194.         {
  195.         gResult = exportBadMode;
  196.         return;
  197.         }
  198.  
  199.     /* Get prompt string */
  200.  
  201.     GetIndString (prompt, kStringsID, 1);
  202.  
  203.     /* Center dialog */
  204.  
  205.     dt = (DialogTHndl) GetResource ('DLOG', putDlgID);
  206.     HNoPurge ((Handle) dt);
  207.  
  208.     CenterDialog (dt);
  209.     where.v = (**dt).boundsRect.top;
  210.     where.h = (**dt).boundsRect.left;
  211.  
  212.     HPurge ((Handle) dt);
  213.  
  214.     /* Ask the user */
  215.  
  216.     SFPutFile (where, prompt, gStuff->filename, nil, &reply);
  217.  
  218.     if (!reply.good)
  219.         {
  220.         gResult = 1;
  221.         return;
  222.         }
  223.  
  224.     gVRefNum = reply.vRefNum;
  225.  
  226.     err = FSDelete (reply.fName, gVRefNum);
  227.  
  228.     err = Create (reply.fName, gVRefNum, '????', '????');
  229.  
  230.     if (err != noErr)
  231.         {
  232.         gResult = err;
  233.         return;
  234.         }
  235.  
  236.     err = FSOpen (reply.fName, gVRefNum, &gFRefNum);
  237.  
  238.     if (err != noErr)
  239.         {
  240.         gResult = err;
  241.         return;
  242.         }
  243.  
  244.     /* Request first block of image */
  245.  
  246.     RequestNext (0);
  247.  
  248.     }
  249.  
  250. #undef kStringsID
  251.  
  252. /*****************************************************************************/
  253.  
  254. /* Processes the next chunk of the image. */
  255.  
  256. void DoContinue (void)
  257.  
  258.     {
  259.     OSErr err;
  260.     short row;
  261.     long count;
  262.     
  263.     for (row = gStuff->theRect.top; row < gStuff->theRect.bottom; row++)
  264.         {
  265.         
  266.         /* See if user was aborted the operation */
  267.  
  268.         if (TestAbort ())
  269.             {
  270.             gResult = 1;
  271.             return;
  272.             }
  273.  
  274.         /* Update the progress indicator */
  275.  
  276.         UpdateProgress ((long) row, (long) gStuff->imageSize.v);
  277.  
  278.         /* Write out this row of the image */
  279.         
  280.         count = gStuff->planes * (long) gStuff->imageSize.h;
  281.  
  282.         err = FSWrite (gFRefNum,
  283.                        &count,
  284.                        (Ptr) ((long) (gStuff->data) + gStuff->rowBytes *
  285.                                            (row - gStuff->theRect.top)));
  286.  
  287.         if (err != noErr)
  288.             {
  289.             gResult = err;
  290.             return;
  291.             }
  292.             
  293.         }
  294.  
  295.     /* Request next block of image */
  296.  
  297.     RequestNext (gStuff->theRect.bottom);
  298.  
  299.     }
  300.  
  301. /*****************************************************************************/
  302.  
  303. /* This routine will always be called if DoStart does not return an error
  304.    (even if DoContinue returns an error or the user aborts the operation).
  305.    This allows the module to perform any needed cleanup. */
  306.  
  307. void DoFinish (void)
  308.  
  309.     {
  310.     OSErr err;
  311.  
  312.     /* Close the file */
  313.  
  314.     err = FSClose (gFRefNum);
  315.  
  316.     if (err != noErr)
  317.         {
  318.         gResult = err;
  319.         return;
  320.         }
  321.  
  322.     /* Flush the volume */
  323.  
  324.     err = FlushVol (nil, gVRefNum);
  325.  
  326.     if (err != noErr)
  327.         {
  328.         gResult = err;
  329.         return;
  330.         }
  331.  
  332.     /* Clear the image's unsaved changes flag */
  333.  
  334.     gStuff->dirty = false;
  335.  
  336.     }
  337.  
  338. /*****************************************************************************/
  339.  
  340. /* Main dispatching routine.  Initializes and sets up the global variables,
  341.    and performs the operation specified by the selector. */
  342.  
  343. pascal void main (selector, stuff, data, result)
  344.  
  345. short selector;
  346. ExportRecordPtr stuff;
  347. long *data;
  348. short *result;
  349.  
  350.     {
  351.     Boolean firstTime;
  352.  
  353.     /* Allow access to global variables */
  354.  
  355.     RememberA0 ();
  356.     SetUpA4 ();
  357.  
  358.     /* Copy the current quickdraw globals into the plug-in local copy */
  359.  
  360.     asm
  361.         {
  362.             MOVE.L    (A5),A0         ; Get address of real quickdraw globals
  363.             SUB.L    #126,A0         ; Move to start
  364.             LEA     randSeed,A1     ; Get address of local copy
  365.             MOVE.W    #64,D0            ; Globals are 65 words long
  366.         @1    MOVE.W    (A0)+,(A1)+     ; Copy a word
  367.             DBF     D0,@1            ; Move to next word
  368.         }
  369.  
  370.     /* See if this is the first time called */
  371.  
  372.     if (!*data)
  373.         {
  374.  
  375.         /* Allocate a handle to hold permanent values */
  376.  
  377.         *data = (long) NewHandle ((long) sizeof (TPermanent));
  378.  
  379.         if (!*data)
  380.             {
  381.             *result = memFullErr;
  382.             RestoreA4 ();
  383.             return;
  384.             }
  385.  
  386.         /* Initialize the permanent values */
  387.  
  388.         InitGlobals ();
  389.  
  390.         }
  391.  
  392.     /* Else restore permanent values */
  393.  
  394.     else
  395.         BlockMove (*((Handle) *data), (Ptr) &gPermanent, (long) sizeof (TPermanent));
  396.  
  397.     /* Perform the requested operation */
  398.  
  399.     gStuff    = stuff;
  400.     gResult = noErr;
  401.  
  402.     switch (selector)
  403.         {
  404.  
  405.         case exportSelectorAbout:
  406.             DoAbout ();
  407.             break;
  408.  
  409.         case exportSelectorPrepare:
  410.             DoPrepare ();
  411.             break;
  412.  
  413.         case exportSelectorStart:
  414.             DoStart ();
  415.             break;
  416.  
  417.         case exportSelectorContinue:
  418.             DoContinue ();
  419.             break;
  420.  
  421.         case exportSelectorFinish:
  422.             DoFinish ();
  423.             break;
  424.  
  425.         default:
  426.             gResult = exportBadParameters;
  427.  
  428.         }
  429.  
  430.     *result = gResult;
  431.  
  432.     /* Save permanent values */
  433.  
  434.     BlockMove ((Ptr) &gPermanent, *((Handle) *data), (long) sizeof (TPermanent));
  435.  
  436.     /* Restore the application's A4 register */
  437.  
  438.     RestoreA4 ();
  439.  
  440.     }
  441.